#include "tjc_screen.hpp"
#include <glog/logging.h>

tjc_screen::tjc_screen(uart_v2 *uart) : _uart(uart),
                                        _rs485_12_pic(tjc_screen_pic_small_no),
                                        _rs485_12_str("null"),
                                        _rs485_34_pic(tjc_screen_pic_small_no),
                                        _rs485_34_str("null"),
                                        _rs485_5678_pic(tjc_screen_pic_small_no),
                                        _rs485_5678_str("null"),
                                        _i2c_pic(tjc_screen_pic_small_no),
                                        _i2c_str("null"),
                                        _spi_pic(tjc_screen_pic_small_no),
                                        _spi_str("null"),
                                        _usb_pic(tjc_screen_pic_small_no),
                                        _usb_str("null"),
                                        _next_page_pic(tjc_screen_pic_big_error),
                                        _number_str("---+---"),
                                        _init_flag(YJ_ERROR),
                                        _is_start(false),
                                        _config_ok_flag (YJ_ERROR)
{
    if (!uart)
    {
        LOG(ERROR) << "tjc_screen uart is null";
        _init_flag = YJ_ERROR;
        return;
    }

    if (uart->uart_open() != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen uart open error";
        _init_flag = YJ_ERROR;
        return;
    }

    _init_flag = YJ_OK;
}

yj_return tjc_screen::_set_text(std::string obj_name, std::string str_value)
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }

    std::lock_guard<std::mutex> lock(_uart_lock);

    std::string send_str = obj_name + ".txt=\"" + str_value + "\"\xff\xff\xff";

    if (_uart->uart_send((uint8_t *)(send_str.c_str()), send_str.length()) == 0)
    {
        LOG(ERROR) << "tjc_screen uart send error";
        return YJ_ERROR;
    }

    return YJ_OK;
}

yj_return tjc_screen::_set_pic(std::string obj_name, tjc_screen_pic pic_id)
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }

    std::string send_str = obj_name + ".pic=" + std::to_string((int)pic_id) + "\xff\xff\xff";

    std::lock_guard<std::mutex> lock(_uart_lock);
    if (_uart->uart_send((uint8_t *)(send_str.c_str()), send_str.length()) == 0)
    {
        LOG(ERROR) << "tjc_screen uart send error";
        return YJ_ERROR;
    }
    return YJ_OK;
}

yj_return tjc_screen::get_value(std::string obj_name, std::string obj_type, uint8_t &read_value)
{
    std::string send_str;
    uint8_t buff[50] = {0};
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }

    if (obj_type.length() == 0)
        send_str = "get " + obj_name + "\xff\xff\xff";
    else
        send_str = "get " + obj_name + "." + obj_type + "\xff\xff\xff";

    // printf("string length: %d\n", send_str.length());
    // for (int i = 0; i < send_str.length(); i++)
    // {
    //     printf("%02x ", (uint8_t *)(send_str.c_str())[i]);
    // }
    // printf("\n");
    std::lock_guard<std::mutex> lock(_uart_lock);
    _uart->uart_flush_all();
    if (_uart->uart_send((uint8_t *)(send_str.c_str()), send_str.length()) == 0)
    {
        LOG(ERROR) << "tjc_screen uart send error";
        return YJ_ERROR;
    }

    if (_uart->uart_recv_one_by_one((uint8_t *)&buff, 8, 100) == 0)
    {
        LOG(ERROR) << "tjc_screen uart recv error";
        return YJ_ERROR;
    }

    if (buff[0] != 0x71 || buff[5] != 0xff || buff[6] != 0xff || buff[7] != 0xff)
    {
        LOG(WARNING) << "tjc_screen uart deserialize error: get: " << send_str;
        for (int i = 0; i < 10; i++)
        {
            printf("%02x ", buff[i]);
        }
        printf("\n");
        return YJ_ERROR;
    }

    read_value = buff[1];
    // LOG(INFO) << "tjc_screen uart recv value: " << (int)read_value;
    return YJ_OK;
}

void tjc_screen::set_status_item(tjc_screen_status status_id, std::string status_context, tjc_screen_pic status_pic)
{
    std::lock_guard<std::mutex> lock(_mutex);
    switch (status_id)
    {
    case tjc_screen_status_rs485_12:
        _rs485_12_str = status_context;
        _rs485_12_pic = status_pic;
        break;
    case tjc_screen_status_rs485_34:
        _rs485_34_str = status_context;
        _rs485_34_pic = status_pic;
        break;
    case tjc_screen_status_rs485_5678:
        _rs485_5678_str = status_context;
        _rs485_5678_pic = status_pic;
        break;
    case tjc_screen_status_i2c:
        _i2c_str = status_context;
        _i2c_pic = status_pic;
        break;
    case tjc_screen_status_spi:
        _spi_str = status_context;
        _spi_pic = status_pic;
        break;
    case tjc_screen_status_usb:
        _usb_str = status_context;
        _usb_pic = status_pic;
        break;
    case tjc_screen_status_next_page:
        _next_page_pic = status_pic;
        break;
    case tjc_screen_number:
        _number_str = status_context;
        break;
    default:
        LOG(ERROR) << "tjc_screen set_status_item error";
        break;
    }
}

yj_return tjc_screen::change_page(tjc_screen_page page)
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }

    std::string send_str = "page " + std::to_string((int)page) + "\xff\xff\xff";
    std::lock_guard<std::mutex> lock(_uart_lock);
    if (_uart->uart_send((uint8_t *)(send_str.c_str()), send_str.length()) == 0)
    {
        LOG(ERROR) << "tjc_screen change_page send error";
        return YJ_ERROR;
    }

    return YJ_OK;
}

yj_return tjc_screen::read_page(tjc_screen_page &page)
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }

    if (get_value("page_num", "", (uint8_t &)page) != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen read page error";
        return YJ_ERROR;
    }
    return YJ_OK;
}

yj_return tjc_screen::fresh_status_screen()
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }
    std::lock_guard<std::mutex> lock(_mutex);

    _set_text("rs485_12_str", _rs485_12_str);
    _set_pic("rs485_12_pic", _rs485_12_pic);
    _set_text("rs485_34_str", _rs485_34_str);
    _set_pic("rs485_34_pic", _rs485_34_pic);
    _set_text("rs485_5678_str", _rs485_5678_str);
    _set_pic("rs485_5678_pic", _rs485_5678_pic);
    _set_text("i2c_str", _i2c_str);
    _set_pic("i2c_pic", _i2c_pic);
    _set_text("spi_str", _spi_str);
    _set_pic("spi_pic", _spi_pic);
    _set_text("usb_str", _usb_str);
    _set_pic("usb_pic", _usb_pic);

    _set_pic("next_page", _next_page_pic);

    return YJ_OK;
}

yj_return tjc_screen::read_start_bt(uint8_t &read_value)
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }
    if (get_value("start_bt", "val", read_value) != YJ_OK)
    {
        return YJ_ERROR;
    }
    return YJ_OK;
}

yj_return tjc_screen::fresh_number_screen()
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }

    if (_set_text("code_str", _number_str) != YJ_OK)
    {
        return YJ_ERROR;
    }

    return YJ_OK;
}

yj_return tjc_screen::set_number(std::string number_str)
{
    if (_init_flag != YJ_OK)
    {
        LOG(ERROR) << "tjc_screen init error";
        return YJ_ERROR;
    }
    std::lock_guard<std::mutex> lock(_mutex);
    _number_str = number_str;
    return YJ_OK;
}

yj_return tjc_screen::detect_start_falg()
{
    uint8_t bt_val = 0;
    if (get_value("start_bt", "val", bt_val) != YJ_OK)
    {
        LOG(ERROR) << "set_start_falg failed";
        return YJ_ERROR;
    }
    std::lock_guard<std::mutex> lock(_mutex);
    if (bt_val == 1)
    {
        _is_start = true;
    }
    else
    {
        _is_start = false;
    }
}
bool tjc_screen::read_start_flag()
{
    std::lock_guard<std::mutex> lock(_mutex);
    if (_is_start)
        change_page(tjc_screen_page_number);
    return _is_start;
}

yj_return tjc_screen::fresh_set_color_sq_screen()
{
    uint8_t _jgq_0_t;
    uint8_t _jgq_1_t;
    uint8_t _jgq_2_t;

    uint8_t _zcq_0_t;
    uint8_t _zcq_1_t;
    uint8_t _zcq_2_t;

    uint8_t bt0_temp;
    uint8_t bt0_temp2;

    if (get_value("bt0", "val", bt0_temp) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }
    if (bt0_temp == 1)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));

        if (get_value("bt0", "val", bt0_temp2) != YJ_OK)
        {
            LOG(ERROR) << "get set screen error";
            return YJ_ERROR;
        }
    }

    if (bt0_temp2 != 1 && bt0_temp2 != 1)
    {
        return YJ_ERROR;
    }

    std::lock_guard<std::mutex> lock(_mutex);

    if (get_value("cjg_0", "val", _jgq_0_t) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }
    if (get_value("cjg_1", "val", _jgq_1_t) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }
    if (get_value("cjg_2", "val", _jgq_2_t) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }
    if (get_value("zc_0", "val", _zcq_0_t) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }
    if (get_value("zc_1", "val", _zcq_1_t) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }
    if (get_value("zc_2", "val", _zcq_2_t) != YJ_OK)
    {
        LOG(ERROR) << "get set screen error";
        return YJ_ERROR;
    }

    _jgq_0 = _jgq_0_t;
    _jgq_1 = _jgq_1_t;
    _jgq_2 = _jgq_2_t;

    _zcq_0 = _zcq_0_t;
    _zcq_1 = _zcq_1_t;
    _zcq_2 = _zcq_2_t;

    _config_ok_flag = YJ_OK;

    return YJ_OK;
}
yj_return tjc_screen::get_set_color_sq_screen(tjc_set_color_en get_witch, uint8_t &get_value)
{
    std::lock_guard<std::mutex> lock(_mutex);
    if(_config_ok_flag != YJ_OK)
    {
        return YJ_ERROR;
    }
    switch (get_witch)
    {
    case tjc_set_color_jgq0:
        get_value = _jgq_0;
        break;
    case tjc_set_color_jgq1:
        get_value = _jgq_1;
        break;
    case tjc_set_color_jgq2:
        get_value = _jgq_2;
        break;
    case tjc_set_color_zcq0:
        get_value = _zcq_0;
        break;
    case tjc_set_color_zcq1:
        get_value = _zcq_1;
        break;
    case tjc_set_color_zcq2:
        get_value = _zcq_2;
        break;
    default:
        return YJ_ERROR;
    }

    

    return YJ_OK;
}